package ifest.ontology;

import java.io.File;
import java.util.Iterator;
import java.util.Set;

import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.reasoner.ConsoleProgressMonitor;
import org.semanticweb.owlapi.reasoner.Node;
import org.semanticweb.owlapi.reasoner.NodeSet;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasonerConfiguration;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
import org.semanticweb.owlapi.reasoner.SimpleConfiguration;
import org.semanticweb.owlapi.util.DefaultPrefixManager;

import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory;

public class ReasonerTest {
	public String run() throws OWLOntologyCreationException{
		String rs="";
		//Test for getting ontology list from repository
	/*	System.out.println(OWLIMTool.getOntologyList());
		//Test for get ontology
		String context = "file://C:/fakepath/ifest-rdf.owl";
		for (String s: OWLIMTool.getOWL(context))
		{
			System.out.println(s);
		}
		//Test for save and load ontology
		String fileName = "D://Working/ontologies/test.owl";
		OWLIMTool.getOWL(context, fileName);*/
		OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
		
		File file = new File ("D://Working/ontologies/test.owl");
		OWLOntology ont = manager.loadOntologyFromOntologyDocument(file);
		System.out.println("load ontology: "+ont.toString());
		
				
		OWLDataFactory factory = manager.getOWLDataFactory();
		 // We need to create an instance of OWLReasoner.  An OWLReasoner provides the basic
        // query functionality that we need, for example the ability obtain the subclasses
        // of a class etc.  To do this we use a reasoner factory.

        // Create a reasoner factory.  In this case, we will use HermiT, but we could also
        // use FaCT++ (http://code.google.com/p/factplusplus/) or Pellet(http://clarkparsia.com/pellet)
        // Note that (as of 03 Feb 2010) FaCT++ and Pellet OWL API 3.0.0 compatible libraries are
        // expected to be available in the near future).

        // For now, we'll use HermiT
        // HermiT can be downloaded from http://hermit-reasoner.com
        // Make sure you get the HermiT library and add it to your class path.  You can then
        // instantiate the HermiT reasoner factory:
        // Comment out the first line below and uncomment the second line below to instantiate
        // the HermiT reasoner factory.  You'll also need to import the org.semanticweb.HermiT.Reasoner
        // package.
    //     OWLReasonerFactory reasonerFactory = null;
        OWLReasonerFactory reasonerFactory = new PelletReasonerFactory();

        // We'll now create an instance of an OWLReasoner (the implementation being provided by HermiT as
        // we're using the HermiT reasoner factory).  The are two categories of reasoner, Buffering and
        // NonBuffering.  In our case, we'll create the buffering reasoner, which is the default kind of reasoner.
        // We'll also attach a progress monitor to the reasoner.  To do this we set up a configuration that
        // knows about a progress monitor.

        // Create a console progress monitor.  This will print the reasoner progress out to the console.
        ConsoleProgressMonitor progressMonitor = new ConsoleProgressMonitor();
        // Specify the progress monitor via a configuration.  We could also specify other setup parameters in
        // the configuration, and different reasoners may accept their own defined parameters this way.
        OWLReasonerConfiguration config = new SimpleConfiguration(progressMonitor);
        // Create a reasoner that will reason over our ontology and its imports closure.  Pass in the configuration.
        OWLReasoner reasoner = reasonerFactory.createReasoner(ont, config);

        // Ask the reasoner to do all the necessary work now
        reasoner.precomputeInferences();

        // We can determine if the ontology is actually consistent (in this case, it should be).
        boolean consistent = reasoner.isConsistent();
        System.out.println("Consistent: " + consistent);
        System.out.println("\n");

        // We can easily get a list of unsatisfiable classes.  (A class is unsatisfiable if it
        // can't possibly have any instances).  Note that the getUnsatisfiableClasses method
        // is really just a convenience method for obtaining the classes that are equivalent
        // to owl:Nothing.  In our case there should be just one unsatisfiable class - "mad_cow"
        // We ask the reasoner for the unsatisfiable classes, which returns the bottom node
        // in the class hierarchy (an unsatisfiable class is a subclass of every class).
        Node<OWLClass> bottomNode = reasoner.getUnsatisfiableClasses();
        // This node contains owl:Nothing and all the classes that are equivalent to owl:Nothing -
        // i.e. the unsatisfiable classes.
        // We just want to print out the unsatisfiable classes excluding owl:Nothing, and we can
        // used a convenience method on the node to get these
        Set<OWLClass> unsatisfiable = bottomNode.getEntitiesMinusBottom();
        if (!unsatisfiable.isEmpty()) {
            System.out.println("The following classes are unsatisfiable: ");
            for(OWLClass cls : unsatisfiable) {
                System.out.println("    " + cls);
            }
        }
        else {
            System.out.println("There are no unsatisfiable classes");
        }
        System.out.println("\n");

        //Get all ToolTypeArtifact
        OWLDataFactory fac = manager.getOWLDataFactory();
        OWLClass cls = fac.getOWLClass("ToolTypeArtifact",pm);
        NodeSet<OWLNamedIndividual> individualsNodeSet = reasoner.getInstances(cls, true);
        Set<OWLNamedIndividual> individuals = individualsNodeSet.getFlattened();
                   System.out.println("Instances of ToolArtifact: ");
                   rs+="Instances of ToolArtifact: ";
        for(OWLNamedIndividual ind : individuals) {
        	                System.out.println("    " + ind);
        	                rs=rs+ "    " + ind.toStringID();
        	                Node<OWLNamedIndividual> same_indis = reasoner.getSameIndividuals(ind);        	           
        	                System.out.println("same as ");
        	                rs+=" same as "; 
        	                Iterator<OWLNamedIndividual> ite = same_indis.iterator();
        	                OWLNamedIndividual same_indi = null;
        	                while (ite.hasNext())
        	                {
        	                	same_indi = ite.next();
        	                	if (!same_indi.equals(ind))
        	                	{
        	                		rs+=same_indi.toStringID();
        	                	}
        	                
        	                }
        	                
        	            }
        	            System.out.println("\n");
        	            rs+=";\n";
       return rs;
}


private static void print(Node<OWLClass> parent, OWLReasoner reasoner, int depth) {
    // We don't want to print out the bottom node (containing owl:Nothing and unsatisfiable classes)
    // because this would appear as a leaf node everywhere
    if(parent.isBottomNode()) {
        return;
    }
    // Print an indent to denote parent-child relationships
    printIndent(depth);
    // Now print the node (containing the child classes)
    printNode(parent);
    for(Node<OWLClass> child : reasoner.getSubClasses(parent.getRepresentativeElement(), true)) {
        // Recurse to do the children.  Note that we don't have to worry about cycles as there
        // are non in the inferred class hierarchy graph - a cycle gets collapsed into a single
        // node since each class in the cycle is equivalent.
        print(child, reasoner, depth + 1);
    }
}

private static void printIndent(int depth) {
    for(int i = 0; i < depth; i++) {
        System.out.print("    ");
    }
}

private static DefaultPrefixManager pm = new DefaultPrefixManager("http://www.obeonetwork.org/ontologies/spem/ifest.owl#");

private static void printNode(Node<OWLClass> node) {
    // Print out a node as a list of class names in curly brackets
    System.out.print("{");
    for(Iterator<OWLClass> it = node.getEntities().iterator(); it.hasNext(); ) {
        OWLClass cls = it.next();
        // User a prefix manager to provide a slightly nicer shorter name
        System.out.print(pm.getShortForm(cls));
        if (it.hasNext()) {
            System.out.print(" ");
        }
    }
    System.out.println("}");
}

 
}
